package homeTask3;

import homeTask3.Logger.LogLevel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * Привет! 
 * Договаривались, что я перешлю точную формулировку домашнего задания. 
 * Итак, я буду ждать от вас к среде 
 * - исправленную версию кода, который мы смотрели на семинаре 
 * - реализацию чтения массива для сортировки из файла.
 * О втором подробнее. Когда мы на предыдущем задании писали обфусцированную сортировку, 
 * то input (aka формат массива для сортировки) не был оговорен. Кто-то генерил массив, 
 * кто-то получал от пользователя, кто-то задавал статически. Теперь же мы говорим, 
 * что массив извлекается из файла1 и, отсортированный, записывается в файл2. 
 * 
 * Имена файлов принимаются в качестве параметров командной строки. Формат хранения массива 
 * остается на Ваше усмотрение - мне приятен CSV, но кому-то мил XML.
 * Обязательным условием принятия задания является корректная обработка ошибок 
 * (файл может не присутствовать или быть запрещенным от чтения) и скорость 
 * (чтение one-by-one с диска это архивредно). Про скорость рекомендую использовать мапирование 
 * файла в память (системный вызов - mmap/CreateFileMapping) или применить какую-то библиотеку 
 * с read-ahead чтением и кэшированной записью. Отдельно обдумайте, чтобы Вас не привел 
 * к крешу 8 гигабайтный файл в 32-битном процессе 
 * 
 * Примечание:
 * те немногие, кто был освобожден от предыдущего домашнего задания, 
 * могут с легкостью использовать qsort или просто выводить массив из одного файла в другой не сортированным. 
 * */

public class FileWorker {

	private final static int MAX_BUBBLE_SORT_SIZE = 50;

	public static void main(String[] args) {	
		if(args.length != 2){
			System.out.println("number of arguments is wrong(expected two names of files)");
			System.exit(0);
		}
		
//		Random rnd = new Random();
//		ArrayList<Integer> array = new ArrayList<Integer>();
//		for(int i = 0; i < 10000000; i++)
//			array.add(rnd.nextInt(1000000));
//		FileMapper fm = new FileMapper("output.txt", "input.txt");
//		fm.writeOutput(array);
		
		
		
		Logger logger = Logger.getLogger(LogLevel.DEBUG);
		Sorter<Integer> sorter;
		
		FileMapper fm = null;
		List<Integer> array = null;
		
		fm = new FileMapper(args[0], args[1]);

		List<byte[]> byteArray;
		Sorter<byte[]> byteSorter = new IntAsBytesSorter();
		
		
		//before increasing performance
		for(int i = 0; i < 1; i++){
			long start = System.currentTimeMillis();
			
			fm = new FileMapper(args[0], args[1]);
			array = fm.getListOfInt2();
			System.out.println("Before: getListOfInt(): " + (System.currentTimeMillis() - start));
			start = System.currentTimeMillis();
			
			sorter = array.size() > MAX_BUBBLE_SORT_SIZE ? new StandartSorter<Integer>() : new BubbleSorter<Integer>();
			logger.debug("Chosen sorter: " + sorter.getClass().getName(), System.out);
			
			List<Integer> l = sorter.sort(array);
			System.out.println("\tSorting: " + (System.currentTimeMillis() - start));
			start = System.currentTimeMillis();
			fm.writeOutput(l);
			System.out.println("\tWriting: " + (System.currentTimeMillis() - start));
		}
		
		//after increasing performance
		for(int i = 0; i < 1; i++){
			long start = System.currentTimeMillis();
			
			fm = new FileMapper(args[0], "output2.txt");
			byteArray = fm.getListOfBytes();
			System.out.println("After: getListOfBytes(): " + (System.currentTimeMillis() - start));
			start = System.currentTimeMillis();
			List<byte[]> l = byteSorter.sort(byteArray);
			System.out.println("\tSorting: " + (System.currentTimeMillis() - start));
			start = System.currentTimeMillis();
			fm.writeByteOutput(l);
			System.out.println("\tWriting: " + (System.currentTimeMillis() - start));
		}

		logger.flush();
	}
}









